package me.zhengjie.modules.finance.factory.entity;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import me.zhengjie.modules.basic.domain.BasicAe03;
import me.zhengjie.modules.basic.mapper.BasicAe03Mapper;
import me.zhengjie.modules.finance.factory.vo.FundBillsInfoVO;
import me.zhengjie.modules.finance.factory.vo.FundBillsSummaryVO;
import me.zhengjie.modules.finance.mapper.FinanceAd01Mapper;
import me.zhengjie.modules.logs.domain.BusinessLog;
import me.zhengjie.modules.logs.service.BusinessLogService;
import me.zhengjie.modules.sequence.domain.Sequence;
import me.zhengjie.modules.sequence.service.SequenceService;
import me.zhengjie.tool.DateUtil;
import me.zhengjie.tool.ListUtil;
import me.zhengjie.tool.MyMap;
import me.zhengjie.tool.NPETool;
import me.zhengjie.util.ValidateUtil;
import me.zhengjie.vo.Constant;
import me.zhengjie.vo.YHConstants;

import javax.annotation.Resource;
import java.io.IOException;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author ly
 * @Description
 * @Date 20:19 2025/6/8
 **/
public class FundBillsInfoApprove {
    private static final long serialVersionUID = 1234567L;
    private final SequenceService sequenceService;
    private final BasicAe03Mapper basicAe03Mapper;
    private final FinanceAd01Mapper financeAd01Mapper;
    BusinessLogService businessLogService;


    /**
     * 收支类型
     */
    protected String aaa039;
    /**
     * 是否线下支付
     */
    protected String bad112;
    //机构银行信息
    protected Map<String, MyMap> banks;

    /**
     * 产生单据信息
     */
    protected List<FundBillsInfoVO> billInfoVOS;

    /**
     * 单据汇总信息
     */
    protected List<FundBillsSummaryVO> fundBillsSummaryVOS;

    public FundBillsInfoApprove(List<Map> inputs, SequenceService sequenceService, BasicAe03Mapper basicAe03Mapper, FinanceAd01Mapper financeAd01Mapper, BusinessLogService businessLogService) {
        this.sequenceService = sequenceService;
        this.basicAe03Mapper = basicAe03Mapper;
        this.financeAd01Mapper = financeAd01Mapper;
        this.businessLogService = businessLogService;
        NPETool.isEmptyThrowException(inputs, "单据信息");
        this.billInfoVOS = new ArrayList<>();
        for (Map bill : inputs) {
            bill.put("billType", "ADD");
            bill.put("aae825", Constant.AAE825_0_F);
            bill.put("aae456", Constant.AAE456_0_F);
            FundBillsInfoVO fundBillsInfoVO = new FundBillsInfoVO(new MyMap(bill));
            this.billInfoVOS.add(fundBillsInfoVO);
        }
    }

    public void dealFundBill() {
        this.fundBillsSummaryVOS = Lists.newArrayList();
        //将需要汇总的单据按照规则分组
        Map<MyMap, List<FundBillsInfoVO>> summaryBill = getBillInfoVOS().stream().collect(Collectors.groupingBy(bill -> getFundBillsSummaryKey53(bill)));
        String aaz617 = sequenceService.nextSequence(new Sequence("aaz617"));
        for (Map.Entry<MyMap, List<FundBillsInfoVO>> entry : summaryBill.entrySet()) {
            String baz617;
            if (summaryBill.entrySet().size() == 1) {
                baz617 = sequenceService.nextSequence(new Sequence("baz617"));
                entry.getKey().put("baz617", baz617);
            } else {
                baz617 = sequenceService.nextSequence(new Sequence("baz617"));
                entry.getKey().put("baz617", baz617);
            }
            entry.getKey().putValue("aaz617", aaz617);
            entry.getKey().putValue("aaz618", aaz617);
            dealSummaryInfo53(entry);
        }
    }

    public void dealSummaryInfo53(Map.Entry<MyMap, List<FundBillsInfoVO>> entry) {
        MyMap summary = entry.getKey();
        List<FundBillsInfoVO> sumBills = entry.getValue();
        if (ValidateUtil.isEmpty(summary.get("aaz617"))) {
            summary.put("aaz617", sequenceService.nextSequence(new Sequence("aaz617")));
            summary.put("aaz618", sequenceService.nextSequence(new Sequence("aaz617")));
        }
        summary.put("bad016", Constant.BAD016_0_WCL);
        summary.put("aae002", ValidateUtil.isEmpty(sumBills.get(0).getAae002()) ? DateUtil.getCurrentTime("yyyyMM") : sumBills.get(0).getAae002());
        //处理单据明细
        BigDecimal aae719 = BigDecimal.ZERO;//金额
        BigDecimal aae717 = BigDecimal.ZERO;//笔数
        Set<String> aaz654s = new HashSet<>();
        for (FundBillsInfoVO sumBill : sumBills) {
            if (BigDecimal.ZERO.compareTo(sumBill.getAae719()) == 0) {
                throw new RuntimeException("存在待支付单据金额为0，单据号：" + sumBill.getAae072());
            }
            aae719 = aae719.add(sumBill.getAae719());
            aae717 = aae717.add(ValidateUtil.isEmpty(sumBill.getAae717())?BigDecimal.ONE:sumBill.getAae717());
            aaz654s.add(sumBill.getAaz654());
        }

        List<Map> updateBills = new ArrayList<>();

        for (String aaz654 : aaz654s) {
            Map upMap = new HashMap();
            upMap.put("aaz654", aaz654);
            upMap.put("aaf216", summary.getAsString("aaf216"));
            upMap.put("aae710", summary.getAsString("aae710"));
            upMap.put("bae710", summary.getAsString("bae710"));
            upMap.put("aad080", summary.getAsString("aad080"));
            upMap.put("aaz617", summary.getAsString("aaz617"));
            upMap.put("aaz618", summary.getAsString("aaz618"));
            upMap.put("baz617", summary.getAsString("baz617"));
            upMap.put("aaf200", summary.getAsString("aaf200"));
            upMap.put("aae013", summary.getAsString("aae013"));
            upMap.put("aaf216s", summary.get("aaf216s"));
            upMap.put("aae145", summary.getAsString("aae145"));
            upMap.put("aae711",Constant.AAE711_1_YJS);
            updateBills.add(upMap);
        }

        summary.put("aae717", aae717);
        summary.put("aae719", aae719);
        summary.put("aae710", summary.getAsString("bae710").substring(0, 4));
        summary.put("aaa039", Constant.AAA039_2_ZC);
        if (ValidateUtil.isNotEmpty(updateBills)) {
//            RepositoryRegister.fundBillsRepository().updateBatchAD01ByBank(updateBills);
        }
        FundBillsSummaryVO fundBillsSummaryVO = new FundBillsSummaryVO(summary);
        this.fundBillsSummaryVOS.add(fundBillsSummaryVO);
    }

    public MyMap getFundBillsSummaryKey53(FundBillsInfoVO bill) {
        MyMap key = new MyMap();
        key.put("aaa039", bill.getAaa039());
        key.put("aae013", bill.getAae013());
        key.put("aaa028", bill.getAaa028());
        key.put("aad080", bill.getAad080());
        key.put("aab359", bill.getAab359());
        key.put("aae718", bill.getAae718());
        key.put("aae710", bill.getAae710());
        key.put("bad112", bill.getBad112());
        if (ValidateUtil.isEmpty(bill.getBad112())) {//默认都是社银
            key.put("bad112", Constant.BAD112_0_SYSF);
        }
        //基于支付方式，如果是单笔支付，单笔一个批次，本地业务类型不截取
        if (bill.getBae710().length() >= 6 && Constant.AAE718_1_PLZF.equals(bill.getAae718())) {
            key.put("bae710", bill.getBae710().substring(0, 6));//按照本地业务款项的前6位进行汇总
        } else {
            key.put("bae710", bill.getBae710());
        }
        key.put("aae145", bill.getAae145());
        List<Map> banks = getSocsiBankInfo53(bill);
        List aaf216s = ListUtil.listMap2ListString(banks,"aaf216");
        key.put("aaf216s",aaf216s);
        //ad02按照社保机构银行类别分组存放
        if(aaf216s.contains(bill.getAaf216())){//本行
            Map bank = banks.stream().filter(map-> bill.getAaf216().equals(map.get("aaf216").toString())).collect(Collectors.toList()).get(0);
            if("12".equals(bill.getAae145())){
                key.put("aaf200", "403");
                key.put("aaf216", "403");
                key.put("aaf217", "中国邮政储蓄银行");
            }else{
                key.put("aaf200", bill.getAaf200());
                key.put("aaf216", bank.get("aaf216"));
                key.put("aaf217", bank.get("aaf217"));
            }
            key.put("aae722", bank.get("aae010"));
            key.put("aae723", bank.get("aae009"));
            key.put("aaz670", bank.get("aaz670"));
        }else{//跨行暂时取第一条
            Map bank = getSocsiBankInfo(bill);
            key.put("aaf200", "900");//暂时记跨行标志 999 他行
            if("12".equals(bill.getAae145())){
                key.put("aaf216", "403");
                key.put("aaf217", "中国邮政储蓄银行");
            }else{
                key.put("aaf216", bank.get("aaf216"));
                key.put("aaf217", bank.get("aaf217"));
            }
            key.put("aae722", bank.get("aae010"));
            key.put("aae723", bank.get("aae009"));
            key.put("aaz670", bank.get("aaz670"));
        }
        return key;
    }


    public List<Map> getSocsiBankInfo53(FundBillsInfoVO bill) {
        if (ValidateUtil.isEmpty(this.banks)) {
            this.banks = new HashMap<>();
        }
        List<Map> bank = new ArrayList<>();
        BasicAe03 query = new BasicAe03();
        query.setAaf216(bill.getAaf216());
        List<BasicAe03> bankList = basicAe03Mapper.getIa20i2(query);
        bankList.forEach(item ->{
            bank.add(JSON.parseObject(JSON.toJSONString(item), Map.class));
        });
        return bank;
    }

    public MyMap getSocsiBankInfo(FundBillsInfoVO bill) {
        String aab359 = bill.getAab359();
        String bae710 = bill.getBae710();
        String aad080 = bill.getAad080();
        if (ValidateUtil.isEmpty(this.banks)) {
            this.banks = new HashMap<>();
        }
        MyMap bank;
        if (ValidateUtil.isNotEmpty(bill.getAae722())) {
            String key =  bill.getAae722() + aad080;
            if (ValidateUtil.isEmpty(banks.get(key))) {
                //原收入记账数据退款，获取原记账信息ad11上的收入社保机构银行、户名
                //通过原记账数据上的账号查询ad64
                Map param = new HashMap();
                param.put("aae010", bill.getAae722());
                param.put("aad080", aad080);
                param.put("aab359", aab359);
//                List<Map> ad64s = NationalQueryRegister.einpFundfinanceQueryService().getAD64(param);
                List<Map> ad64s = new ArrayList<>();
                if (ValidateUtil.isEmpty(ad64s) || ad64s.size() != 1) {
                    throw new RuntimeException("未获取到社保机构账号" + bill.getAae722() + "账户有效信息");
                } else {
                    bank = new MyMap(ad64s.get(0));
                    banks.put(key, bank);
                }
            } else {
                bank = banks.get(key);
            }
        } else {
            String key = aab359 + bae710 + aad080;
            if (ValidateUtil.isEmpty(banks.get(key))) {
                Map param = new HashMap();
                param.put("booksetno", aad080);
                param.put("forgid", aab359);
                if(Constant.AAD080_170_CXJMJBYLBXZT.equals(aad080) || Constant.AAD080_410_GSBXZT.equals(aad080)){
                    param.put("accountowner", "1");
                    param.put("ispooling", "0");
                }else{
                    if(Constant.AAE710_1001_DQDYZC.equals(bae710) || Constant.AAE710_1002_YCXDYZC.equals(bae710) || Constant.BAE710_100204_TSDYZC.equals(bae710)){
                        param.put("accountowner", "1");
                        param.put("ispooling", "0");
                    }else{
                        param.put("accountowners", "2");
                        param.put("ispooling", "1");
                    }
                }
//                List<Map> fesAccounts = RepositoryRegister.financeFesGSMapperRepository().getFesAccount(param);
                List<Map> fesAccounts = new ArrayList<>();
                if (ValidateUtil.isEmpty(fesAccounts)) {
                    throw new RuntimeException("未获取到FES社保机构银行信息");
                }
                List<String > aaz670s = ListUtil.listMap2ListString(fesAccounts,"custid");
                param.clear();
                param.put("aae100", Constant.AAE100_1_YX);
                param.put("bae710", bae710);
                param.put("aad080", aad080);
                param.put("aab359", aab359);
                param.put("aaf200","900");
                param.put("aaz670s", aaz670s);

                param.clear();
                //基于bank查询ad64
                List<Map> ad64s = new ArrayList<>();
                if (ValidateUtil.isEmpty(ad64s)) {
                    throw new RuntimeException("未获取到社保机构银行信息");
                }
                bank = new MyMap(ad64s.get(0));
            } else {
                bank = banks.get(key);
            }
        }
        return bank;
    }


    /**
     * 数据校验
     */
    public void checkData() {
        // 父方法
    }

    public void saveSummaryFundBillsInfo() throws IOException {
        // 日志
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> param = new HashMap<>();
        param.put("aaz002", this.fundBillsSummaryVOS.get(0).getAaz617());
        param.put("aaa121", YHConstants.AAA121_ZFJH);
        param.put("aae016", Constant.AAE016_1_SHTG);
        param.put("aae140", Constant.AAE140_120_JGSYDWGZRYJBYLBX);
        BusinessLog businessLog = BusinessLog.singleLog(param);
        businessLogService.save(businessLog);
        //保存
        List<Map> bills = new ArrayList<>();
        List<Map> sumBills = new ArrayList<>();
        this.billInfoVOS.forEach(item -> {
            item.setAaz617(this.fundBillsSummaryVOS.get(0).getAaz617());
            item.setAaz618(this.fundBillsSummaryVOS.get(0).getAaz617());
            bills.add(JSON.parseObject(JSON.toJSONString(item), Map.class));
        });
        this.fundBillsSummaryVOS.forEach(item -> {
            sumBills.add(JSON.parseObject(JSON.toJSONString(item),Map.class));
        });

        // 更新ad01
        financeAd01Mapper.updateBatchAd01(bills);
        // 新增ad02
        financeAd01Mapper.batchInsertAd02(sumBills);

    }
    public List<FundBillsInfoVO> getBillInfoVOS() {
        return billInfoVOS;
    }

    public List<FundBillsSummaryVO> getFundSummaryInfoVOS() {
        return fundBillsSummaryVOS;
    }

    public String getAaa039() {
        return aaa039;
    }

    public String getBad112() {
        return bad112;
    }
}
